import { defineStore } from 'pinia'
import { 
  getMusicSource, 
  getPlaylist, 
  increasePlayCount,
  clearPlaylist,
  addToPlaylist,
  addToRecentPlay,
  getMusicLyric
} from '@/api/music'
import { addPlayListToQueue } from '@/api/playList'
import { audioEffects } from '@/config/audioEffects'

export interface Music {
  id: string
  title: string
  artist: string
  cover: string
  url: string
  lrc: string
  duration: string
}

export const emptyMusic: Music = {
  id: '',
  title: '',
  artist: '',
  cover: '',
  url: '',
  lrc: '',
  duration: '0'
}

export const usePlayerStore = defineStore('player', {
  state: () => ({
    currentTime: 0,
    duration: 0,
    isPlaying: false,
    currentMusic: emptyMusic,
    playlist: [] as Music[],
    audio: null as HTMLAudioElement | null,
    audioContext: null as AudioContext | null,
    audioSource: null as MediaElementAudioSourceNode | null,
    currentEffect: 'normal',
    effectNodes: {} as Record<string, any>,
    audioInitialized: false,
    lyrics: [] as { time: number; text: string }[],
    currentLyricIndex: -1,
    lyricScrolling: false,
  }),
  
  actions: {
    initAudio() {
      if (!this.audio) {
        this.audio = new Audio()
        this.audio.crossOrigin = 'anonymous'
        this.setupAudioEvents()
      }
    },

    setupAudioEvents() {
      if (!this.audio) return
      
      this.audio.addEventListener('timeupdate', () => {
        if (this.audio) {
          this.currentTime = this.audio.currentTime
          this.updateCurrentLyric(this.audio.currentTime)
        }
      })
      
      this.audio.addEventListener('ended', () => {
        this.isPlaying = false
        this.currentTime = 0
        document.title = this.currentMusic.title || 'Music Player'
      })
    },

    async playMusic(music: Music) {
      try {
        // 重置歌词状态
        this.lyrics = []
        this.currentLyricIndex = -1
        document.title = music.title || 'Music Player'

        // 添加到播放列表
        const isExist = this.playlist.some(item => item.id === music.id)
        if (!isExist) {
          const response = await addToPlaylist(music.id)
          if (response.success) {
            const playlist = await getPlaylist()
            this.setPlaylist(playlist)
          }
        }

        // 播放音乐
        this.currentMusic = music
        if (!this.audio) this.initAudio()
        
        // 加载歌词
        try {
          const lyricText = await getMusicLyric(music.id)
          if (lyricText) {
            this.parseLyric(lyricText)
          } else {
            this.lyrics = []
          }
        } catch (error) {
          console.error('加载歌词失败:', error)
          this.lyrics = []
        }
        
        const source = await getMusicSource(music.id)
        
        if (this.audio) {
          this.audio.crossOrigin = 'anonymous'
          this.audio.src = source.url

          if (!this.audioInitialized) {
            await this.initAudioContext()
            this.audioInitialized = true
          }

          await new Promise((resolve) => {
            this.audio!.onloadedmetadata = resolve
          })
          
          await this.audio.play()
          this.isPlaying = true

          // 添加到最近播放
          await addToRecentPlay(music.id)

          // 检查并增加播放量
          const playedSongs = JSON.parse(localStorage.getItem('playedSongs') || '{}')
          const lastPlayTime = playedSongs[music.id]
          const now = Date.now()
          
          if (!lastPlayTime || (now - lastPlayTime) / (1000 * 60 * 60) >= 24) {
            await increasePlayCount(music.id)
            playedSongs[music.id] = now
            localStorage.setItem('playedSongs', JSON.stringify(playedSongs))
          }
        }
      } catch (error) {
        console.error('播放音乐失败:', error)
        document.title = 'Music Player'
        throw error
      }
    },

    async togglePlay() {
      if (!this.audio) return
      
      if (this.isPlaying) {
        await this.audio.pause()
        document.title = this.currentMusic.title || 'Music Player'
      } else {
        await this.audio.play()
        // 恢复当前歌词显示
        this.updateCurrentLyric(this.currentTime)
      }
      this.isPlaying = !this.isPlaying
    },

    setPlaylist(playlist: Music[]) {
      this.playlist = playlist
      // 如果播放列表为空，重置所有状态
      if (playlist.length === 0) {
        this.resetPlayerState()
      }
    },

    setCurrentTime(time: number) {
      if (this.audio) {
        this.audio.currentTime = time
      }
    },

    setVolume(volume: number) {
      if (this.audio) {
        this.audio.volume = volume
      }
    },

    async clearPlaylist() {
      try {
        const response = await clearPlaylist()
        if (!response.success) {
          throw new Error(response.message)
        }
        this.resetPlayerState()
        return response
      } catch (error) {
        console.error('清空播放列表失败:', error)
        throw error
      }
    },

    async appendMusicToQueue(music: Music) {
      try {
        const response = await addToPlaylist(music.id)
        if (!response.success) {
          throw new Error(response.message)
        }

        const playlist = await getPlaylist()
        this.setPlaylist(playlist)

        if (!this.currentMusic.id && playlist.length > 0) {
          this.currentMusic = playlist[0]
          await this.playMusic(this.currentMusic)
        }

        return response
      } catch (error) {
        console.error('添加音乐到播放列表失败:', error)
        throw error
      }
    },

    async appendPlaylistToQueue(playlistId: string) {
      try {
        const response = await addPlayListToQueue(playlistId)
        if (response.success) {
          // 重新获取播放列表
          const playlist = await getPlaylist()
          this.setPlaylist(playlist)
        }
        return response
      } catch (error) {
        console.error('添加歌单到播放列表失败:', error)
        return { success: false, message: '添加失败' }
      }
    },

    async playPlaylist(playlistId: string) {
      try {
        // 先清空当前播放列表
        await clearPlaylist()
        this.playlist = []
        
        // 添加歌单所有歌曲到播放列表
        const response = await addPlayListToQueue(playlistId)
        if (response.success) {
          // 获取更新后的播放列表
          const playlist = await getPlaylist()
          this.setPlaylist(playlist)
          
          // 如果有歌曲则播放第一首
          if (playlist.length > 0) {
            await this.playMusic(playlist[0])
          }
        }
        return response
      } catch (error) {
        console.error('播放歌单失败:', error)
        return { success: false, message: '播放失败' }
      }
    },

    async initAudioContext() {
      try {
        // 如果已经存在 audioContext，则返回
        if (this.audioContext && this.audioSource) return

        // 创建新的 AudioContext
        this.audioContext = new AudioContext()

        // 确保 audio 元素存在
        if (!this.audio) {
          this.initAudio()
        }

        // 确保设置了 crossOrigin
        if (this.audio) {
          this.audio.crossOrigin = 'anonymous'
          
          // 创建 MediaElementSource
          this.audioSource = this.audioContext.createMediaElementSource(this.audio)
          this.audioSource.connect(this.audioContext.destination)
        }
      } catch (error) {
        console.error('初始化音频上下文失败:', error)
        throw error
      }
    },

    async setAudioEffect(effectId: string) {
      try {
        if (!this.audio || !this.audio.src) {
          console.warn('没有正在播放的音乐')
          return
        }

        // 确保 AudioContext 已初始化
        if (!this.audioContext || !this.audioSource) {
          await this.initAudioContext()
        }

        // 断开之前的效果连接
        if (this.effectNodes[this.currentEffect]) {
          this.audioSource?.disconnect()
          Object.values(this.effectNodes[this.currentEffect]).forEach(node => {
            node.disconnect()
          })
        }

        this.currentEffect = effectId

        // 如果是原声，直接连接到输出
        if (effectId === 'normal') {
          this.audioSource?.connect(this.audioContext!.destination)
          return
        }

        // 从配置中获取音效设置
        const effect = audioEffects.find(e => e.id === effectId)
        if (!effect) {
          console.warn('未找到音效配置:', effectId)
          return
        }

        // 设置音效
        const { nodes, connections } = effect.setup(this.audioContext!)
        this.effectNodes[effectId] = nodes

        // 连接第一个节点
        if (connections.length > 0) {
          this.audioSource!.connect(Object.values(nodes)[0])
        }

        // 建立节点之间的连接
        connections.forEach(([fromNode, toNode, outputIndex, inputIndex]) => {
          if (outputIndex !== undefined && inputIndex !== undefined) {
            fromNode.connect(toNode, outputIndex, inputIndex)
          } else {
            fromNode.connect(toNode)
          }
        })

      } catch (error) {
        console.error('设置音效失败:', error)
        throw error
      }
    },

    // 解析歌词文本
    parseLyric(lrcText: string) {
      const lines = lrcText.split('\n')
      const lyrics: { time: number; text: string }[] = []
      const timeRegex = /\[(\d{2}):(\d{2})[\.:](\d{1,3})(?:\d*)\](.*)/
      
      lines.forEach(line => {
        const match = timeRegex.exec(line)
        if (match) {
          const minutes = parseInt(match[1])
          const seconds = parseInt(match[2])
          const milliseconds = parseInt(match[3].padEnd(3, '0'))
          const text = match[4].trim()
          
          const time = minutes * 60 + seconds + milliseconds / 1000
          if (text) {
            lyrics.push({ time, text })
          }
        }
      })
      
      this.lyrics = lyrics.sort((a, b) => a.time - b.time)
    },

    // 二分
    binarySearchLyric(lyrics: { time: number; text: string }[], time: number): number {
      let left = 0
      let right = lyrics.length - 1

      while (left <= right) {
        const mid = Math.floor((left + right) / 2)
        
        // 找到最后一个时间小于等于当前时间的歌词
        if (lyrics[mid].time <= time) {
          if (mid === lyrics.length - 1 || lyrics[mid + 1].time > time) {
            return mid
          }
          left = mid + 1
        } else {
          right = mid - 1
        }
      }
      
      return -1
    },

    // 更新歌词
    updateCurrentLyric(time: number) {
      // 如果没有歌词或未在播放，显示歌曲名
      if (this.lyrics.length === 0 || !this.isPlaying) {
        document.title = this.currentMusic.title || 'Music Player'
        return
      }
      
      const index = this.binarySearchLyric(this.lyrics, time)
      
      // 如果找到了新的歌词索引，且与当前不同
      if (index !== -1 && this.currentLyricIndex !== index) {
        this.currentLyricIndex = index
        document.title = this.lyrics[index].text
        this.scrollToCurrentLyric()
      }
    },

    // 新增：滚动到当前歌词的方法
    scrollToCurrentLyric() {
      if (this.lyricScrolling) return

      const container = document.querySelector('.lyrics-wrapper')
      const activeLyric = document.querySelector('.lyric-line.active')
      
      if (container && activeLyric) {
        this.lyricScrolling = true
        
        // 获取容器和歌词元素的尺寸信息
        const containerHeight = container.clientHeight
        const lyricHeight = (activeLyric as HTMLElement).clientHeight
        
        // 计算滚动位置
        const scrollTop = (activeLyric as HTMLElement).offsetTop - 
                         (containerHeight / 2) + (lyricHeight / 2)
        
        // 使用平滑滚动
        container.scrollTo({
          top: scrollTop,
          behavior: 'smooth'
        })

        // 滚动结束后重置状态
        setTimeout(() => {
          this.lyricScrolling = false
        }, 300) // 300ms 后重置，与 CSS transition 时间匹配
      }
    },

    // 在 state 中添加一个方法来统一处理标题重置
    resetPlayerState() {
      if (this.audio) {
        this.audio.pause()
        this.audio.src = ''
      }
      this.playlist = []
      this.currentMusic = emptyMusic
      this.isPlaying = false
      this.currentTime = 0
      this.duration = 0
      this.lyrics = []
      this.currentLyricIndex = -1
      document.title = 'Music Player'
      
      // 触发进度更新，确保UI同步
      if (this.audio) {
        this.audio.dispatchEvent(new Event('timeupdate'))
        this.audio.dispatchEvent(new Event('loadedmetadata'))
      }
    }
  }
}) 
